<template>
    <el-dialog v-model="data.dlg.show" :title="data.dlg.title" width="450">
        <el-table :data="data.dlg.table">
            <el-table-column property="idx" label="序号" />
            <el-table-column property="value" label="值" />
            <el-table-column property="-" label="" />
        </el-table>
    </el-dialog>
    <el-button id="btn_setting" type="primary" :icon="HomeFilled" @click="go(0);">首页</el-button>
    <el-button id="btn_setting" type="primary" :icon="Back" @click="go(-1);">返回</el-button>
    <el-button id="btn_setting" type="primary" :icon="Refresh" @click="refresh">刷新</el-button>

    <main class="graph-container">
        <div id="graph-container" />
    </main>
</template>

<script setup  lang="ts">
import { onMounted, reactive } from "vue";
import { Refresh, HomeFilled, Back } from '@element-plus/icons-vue'
// import { ElMessage, ElMessageBox } from 'element-plus'

import { Graph } from '@antv/x6'
// import { Transform } from '@antv/x6-plugin-transform'
// import { Selection } from '@antv/x6-plugin-selection'
// import { Snapline } from '@antv/x6-plugin-snapline'
import { Keyboard } from '@antv/x6-plugin-keyboard'
// import { Clipboard } from '@antv/x6-plugin-clipboard'
// import { History } from '@antv/x6-plugin-history'

import { easyapi, getParams } from '@/lib/lib.ts'

interface Data {
    [property: string]: any
}

let graph: Graph;

const data: Data = reactive({
    // curNode: "",//当前选择的节点
    dlg: { //节点对话框
        //  node: {},//选择的节点
        title: "数组查看",//标题
        show: false, //是否显示
        dataType: 0,//对话框类型
        table: [],
    },
    lastEdgeColor: "",
    fileName: "",//画布文件名
    zoom: 1,//放大级别
})

//加载需要预览的文件
const loadFile = (path: string) => {
    let url = encodeURI(`/v1/api/file?path=${path}`)
    easyapi(url, "get", null, (rsp: { data: { data: string; }; }) => {
        let obj = JSON.parse(rsp.data.data);
        loadGraphWithoutCheck(obj);
        setTimeout(refresh, 200);
    })
}

const go = (step: number) => {
    if (step == 0) {
        location.href = "/";
        return;
    }
    history.go(step);
}

//更新线条标签
const updateEdge = (port: any) => {
    if (port && port.edge != "") {
        // console.log(port)
        let edge: any = graph.getCellById(port.edge);
        let edgeColor: string = '#404040';
        console.log(port.Value)
        if (port.Bad) {
            edgeColor = '#ff0000';
            edge.attr('line', { stroke: edgeColor });
        } else if (typeof port.Value == "boolean") {
            if (port.Value) {
                edgeColor = '#00aa00';
                edge.attr('line', { stroke: edgeColor });
            } else {
                //edgeColor = '#999999';
                edge.attr('line', { stroke: '#9999CC' });
           }
        }
        let text: string = ""
        if (Array.isArray(port.Value)) {
            text = "array"
        } else {
            text = String(port.Value);
        }
        if (!edge.data) {
            edge.data = {};
        }
        edge.data.Value = port.Value;
        edge.data.EnQ = port.Bad;
        edge.labels = [{
            attrs: {
                label: {
                    text: text,
                    fill: edgeColor,
                    fontSize: 12,
                    strokeWidth: 0,
                },
            },
            position: {
                distance: 0,
                offset: {
                    x: 15,
                },
            },
        }, {
            attrs: {
                label: {
                    text: text,
                    fill: edgeColor,
                    fontSize: 12,
                    strokeWidth: 0,
                },
            },
            position: {
                distance: 1,
                offset: {
                    x: -10,
                },
            },
        }];
    }
}
//刷新参数数据
const refresh = () => {
    let params = getParams();
    // console.log(params)
    let path = params["path"];
    let category = params["category"];
    let devid = params["devid"];
    let extend = params["extend"];
    let url = encodeURI(`/v1/api/paramsdata?path=${path}&category=${category}&extend=${extend}&devid=${devid}`)
    // console.log(url);

    easyapi(url, "get", null, (rsp: { data: { data: string; }; }) => {
        let obj: any = rsp.data.data;
        obj.Nodes.forEach((node: any) => {
            // console.log(node, node.ID, node.Name, node.Bad, node.EnQ)
            let n: any = graph.getCellById(node.ID) //获取画布上的node
            if (node.Bad) {
                n.attr('body/fill', '#ff0000')
            } else {
                n.attr('body/fill', '#fff')
            }
            // console.log(n)
            if (n.data.modelId == "2") {
                if (node.Y && node.Y.edge) {
                    updateEdge(node.Y);
                }
            }

            const nodePorts = n.getPorts(); //获取连接装的端口找到端口对应的名称
            nodePorts.forEach((port: any) => {
                if (port.data.name) {
                    let p: any = node[port.data.name];//原始节点对应的标签名
                    updateEdge(p);
                }
            })
        })
    })
}


//加载图形，不做任何检查
const loadGraphWithoutCheck = (obj: any) => {
    let ns: any = [];//node 集合
    let edges: any = [];
    if (obj.filename) {
        data.fileName = obj.filename;
    }
    if (obj.zoom) {
        data.zoom = obj.zoom;
    }
    graph.clearCells();

    obj.cells.forEach((item: any) => {
        if (item.shape == "edge") {
            edges.push(item);
        } else {
            ns.push(item);
        }
    })
    graph.addNodes(ns);
    graph.addEdges(edges);
    if (data.zoom) {
        graph.zoomTo(data.zoom);
    }
}

// #region 初始化画布
onMounted(() => {
    // #region 初始化画布
    graph = new Graph({
        container: document.getElementById('graph-container') as HTMLElement,
        mousewheel: {
            enabled: true,
            zoomAtMousePosition: true,
            modifiers: 'ctrl',
            minScale: 0.5,
            maxScale: 3,
        },
        panning: {
            enabled: true,
            // modifiers: 'ctrl',
        },
        translating: { restrict: true },
        connecting: {
            router: {
                name: 'manhattan',
                args: {
                    startDirections: ['right'],
                    endDirections: ['left'],
                    padding: 15,
                },
            },
            anchor: 'center',
            connectionPoint: 'boundary',
            snap: {
                radius: 20,
            },
        }
    })

    //注册算子节点
    Graph.registerNode(
        'op-rect',
        {
            inherit: 'rect',
            width: 55,
            height: 40,
            attrs: {
                label: {
                    refY: -10,
                    fontSize: 14,
                },
            },
            ports: {
                groups: {
                    in: {
                        position: 'left',
                        label: {
                            position: {
                                name: 'inside',
                                args: {
                                    attrs: {
                                        text: {
                                            refX: 7,
                                            fontSize: 12,
                                        }
                                    }
                                }
                            }
                        },
                        attrs: {
                            circle: {
                                r: 5,
                                magnet: true,
                                stroke: '#31d0c6',
                                fill: '#fff',
                                strokeWidth: 2,
                            },
                        },
                    },
                    out: {
                        position: 'right',
                        label: {
                            position: {
                                name: 'inside',
                                args: {
                                    attrs: {
                                        text: {
                                            refX: -7,
                                            fontSize: 12,
                                        }
                                    }
                                }
                            }
                        },
                        attrs: {
                            circle: {
                                r: 5,
                                magnet: true,
                                stroke: '#31d0c6',
                                fill: '#fff',
                                strokeWidth: 2,
                            },
                        },
                    },
                },
            },
        },
        true,
    );

    //注册IO算子
    Graph.registerNode(
        'op-rect-io',
        {
            inherit: 'rect',
            width: 100,
            ports: {
                groups: {
                    in: {
                        position: 'right',
                        attrs: {
                            circle: {
                                r: 5,
                                magnet: true,
                                stroke: '#31d0c6',
                                fill: '#fff',
                                strokeWidth: 2,
                            },
                        },
                    },
                    out: {
                        position: 'left',
                        attrs: {
                            circle: {
                                r: 5,
                                magnet: true,
                                stroke: '#31d0c6',
                                fill: '#fff',
                                strokeWidth: 2,
                            },
                        },
                    },
                },
            },
        },
        true,
    )

    // #region 使用插件
    graph
        .use(new Keyboard())

    // 放大
    graph.bindKey(['ctrl+1', 'meta+1'], () => {
        const zoom = graph.zoom()
        if (zoom < 1.5) {
            graph.zoom(0.1)
        }
    })

    //缩小
    graph.bindKey(['ctrl+2', 'meta+2'], () => {
        const zoom = graph.zoom()
        if (zoom > 0.5) {
            graph.zoom(-0.1)
        }
    })

    //线条高亮
    graph.on('edge:mouseenter', ({ edge }) => {
        data.lastEdgeColor = edge.attr('line/stroke')
        //console.log(data.lastEdgeColor);
        edge.attr('line', { stroke: '#1890ff' });
        //data.zIndex = edge.getZIndex();
        edge.setZIndex(200);
    })

    //线恢复正常
    graph.on('edge:mouseleave', ({ edge }) => {
        // console.log(data.lastEdgeColor);
        if (data.lastEdgeColor != "") {
            edge.attr('line/stroke', data.lastEdgeColor);
        } else {
            edge.attr('line', { stroke: '#A2B1C3' });
        }
        edge.setZIndex(0);
        if (edge.hasTool('vertices')) {
            edge.removeTool('vertices')
            document.body.style.cursor = "default"
        }
    })

    //点击连线事件
    graph.on('edge:dblclick', ({ edge }) => {
        if (edge.data && Array.isArray(edge.data.Value)) {
            //console.log(edge.data)
            let grid: any = [];
            edge.data.Value.forEach((val: any, idx: any) => {
                grid.push({ idx: idx + 1, value: val })
            })
            data.dlg.table = grid;
            data.dlg.show = true;
        }
    })

    let params: any = getParams()
    loadFile(params['path'])
})

</script>

<style scoped>
.graph-container {
    height: calc(100% - 40px);
}

.graph-container>div {
    width: 100%;
    height: 100%;
}
</style>
